# -*- coding: utf-8 -*-
import decimal
import logging
from collections import Counter
import json
import time
from decimal import Decimal
from datetime import date, datetime
from flask import jsonify
from wt.api_service.api_imp.wt_task_api import WtTaskAPI
from wt.api_service.api_imp.ws_task_api import WsTaskAPI
from wt.auto_test_case.database_case import DatabaseCase
from wt.connector.db_manager import db_mysql_manager
from loguru import logger


class WTModel:

    def __init__(self):
        super().__init__()
        self.wt_api = WtTaskAPI()
        self.ws_api = WsTaskAPI()
        self.d_api = DatabaseCase()

        self.m_mysql = db_mysql_manager.DBMysqlManager()


    def alert_set_or_query(self, jobid_or_jobname, method):
        res = self.wt_api.alert_set_or_query(jobid_or_jobname, method)
        return jsonify({"res": res})

    def create_wt_job(self, project_name, job_name, job_mode, source_type, sink_type, source_table_is_customer,
                      sink_table_is_customer, source_config, job_type, sink_config):
        """
        创建wt 任务，create_wt_job("v26", "v26_auto_batch_mysql_to_mysql", "BATCH", "JDBC-Mysql", "JDBC-Mysql", "aaa1", "source_config")
        :param project_name:
        :param job_name:
        :param job_mode:
        :param source_type:
        :param sink_type:
        :return:
        """
        create_wt_res = self.wt_api.create_wt_integra_task(project_name, job_name, job_mode, source_type, sink_type,
                                                           source_table_is_customer, sink_table_is_customer,
                                                           source_config=source_config, job_type=job_type,
                                                           sink_config=sink_config)
        return jsonify({"create_wt_res": create_wt_res})

    def create_ws_workflow(self, project_name, job_name, wt_type):
        """
        创建ws工作流，create_ws_workflow("v26", "v26_auto_batch_mysql_to_mysql", "BATCH")
        :param project_name:
        :param job_name:
        :param wt_type:
        :return:
        """
        create_ws_res = self.ws_api.create_ws_task(project_name, job_name, wt_type)
        return jsonify({"create_ws_res": create_ws_res})

    def run_ws_task(self, project_name, job_name, wt_type, run_param):
        """
        运行任务，run_ws_task("v26", "v26_auto_batch_mysql_to_mysql", "BATCH")
        :param project_name:
        :param job_name:
        :param wt_type:
        :return:
        """
        run_task_res = self.ws_api.run_ws_task(project_name, job_name, wt_type, run_param)
        return jsonify({"run_task_res": run_task_res})

    def wait_task_complete(self, project_name, job_name, wt_type):
        """
        等待任务结束，wait_task_complete("v26", "v26_auto_batch_mysql_to_mysql", "BATCH")
        :param project_name:
        :param job_name:
        :param wt_type:
        :return:
        """
        run_task_res = self.ws_api.block_until_task_complete(project_name, job_name, wt_type)
        return jsonify({"run_task_res": run_task_res})

    def get_task_web_state(self, project_name, job_name, wt_type):
        """
        获取任务状态，get_task_web_state("v26", "v26_auto_batch_mysql_to_mysql", "BATCH", "state")
        :param project_name:
        :param job_name:
        :param wt_type:
        :return:
        """
        run_task_state = self.wt_api.get_wt_instance_task_info(project_name, job_name, wt_type, "state")
        return jsonify({"run_task_state": run_task_state})

    def get_task_web_write_count(self, project_name, job_name, wt_type):
        """
        获取任务总数，get_task_web_write_count("v26", "v26_auto_batch_mysql_to_mysql", "BATCH", "writeRowCount")
        :param project_name:
        :param job_name:
        :param wt_type:
        :return:
        """
        task_web_write_res = self.wt_api.get_wt_instance_task_info(project_name, job_name, wt_type, "writeRowCount")
        return jsonify({"task_web_write_res": task_web_write_res})

    def get_task_web_read_count(self, project_name, job_name, wt_type):
        """
        获取任务总数，get_task_web_read_count("v26", "v26_auto_batch_mysql_to_mysql", "BATCH", "readRowCount")
        :param project_name:
        :param job_name:
        :param wt_type:
        :return:
        """
        task_web_read_res = self.wt_api.get_wt_instance_task_info(project_name, job_name, wt_type, "readRowCount")
        return jsonify({"task_web_read_res": task_web_read_res})

    def get_wt_task_log(self, project_name, task_name, wt_type):
        wt_log = self.wt_api.get_wt_task_log(project_name, task_name, wt_type)
        res = jsonify({"create_database_res": wt_log})
        return res

    def import_wt_task(self, project_name, job_name):
        import_res = self.wt_api.import_wt_task(project_name, job_name)
        res = jsonify({"create_database_res": import_res})
        return res

    def get_db_source_sink_count(self, source_type, source_table, sink_type, sink_table):
        """
        获取db source / sink 数据，get_db_source_sink_count(mysql.qa_source.aaa1,mysql.qa_sink.aaa1,)
        :param sink_table:
        :param sink_type:
        :param source_table:
        :param source_type:
        :return:
        """

        source_count = self.d_api.db_select_count_case(source_type, source_table)
        time.sleep(5)
        sink_count = self.d_api.db_select_count_case(sink_type, sink_table)

        if source_count['message'] and sink_count['message'] == 'Success':
            return jsonify({"source_count": source_count['data'], "sink_count": sink_count['data']})
        else:
            return {'message': 'fail', 'data': "查询失败，请检查数据源模板"}

    def create_database(self, db_type, input_db_name=None):
        """
        创建数据源 create_database("JDBC-Mysql")
        :param input_db_name:
        :param db_type:
        :return:
        """
        create_database_res = self.d_api.create_database_case(db_type, input_db_name)
        res = jsonify({"create_database_res": create_database_res})
        return res

    def del_database(self, db_type, input_db_name=None):
        """
        删除数据源 del_database("JDBC-Mysql")
        :param input_db_name:
        :param db_type:
        :return:
        """
        del_database_res = self.d_api.del_database_case(db_type, input_db_name)
        res = jsonify({"del_database_res": del_database_res})
        return res

    def connect_database(self, db_type, input_db_name=None):
        """
        链接数据源 connect_database("JDBC-Mysql")
        :param input_db_name:
        :param db_type:
        :return:
        """
        connect_database_res = self.d_api.connect_database_case(db_type, input_db_name)
        res = jsonify({"connect_database_res": connect_database_res})
        return res

    def query_database(self, db_type, input_db_name=None):
        """
        查询数据源 query_database("JDBC-Mysql")
        :param input_db_name:
        :param db_type:
        :return:
        """
        database_id = self.d_api.query_database_case(db_type, input_db_name)
        res = jsonify({"query_database_res": {"database_id": database_id}})
        return res

    def get_database_table(self, db_type, input_db_name=None):
        """
        获取数据数据表 get_database_table("JDBC-Mysql")
        :param input_db_name:
        :param db_type:
        :return:
        """
        database_table_res = self.d_api.get_database_table_case(db_type, input_db_name)
        return jsonify({"get_database_table_res": {"database_table": database_table_res}})

    def exec_ssh_command(self, ip, user, passwd, command):
        exec_res = self.d_api.exec_ssh_command(ip, user, passwd, command)
        # res = jsonify({"exec_res": exec_res})
        return jsonify(exec_res)

    def db_create(self, db_type, table, text_type):
        """
        创建数据数据表 db_create("JDBC-Mysql","qa_source.test1")
        :param text_type:
        :param db_type:
        :param table:
        :return:
        """
        db_create_res = self.d_api.db_create_case(db_type, table, text_type)
        return jsonify(db_create_res)

    def db_delete(self, db_type, table, text_type):
        """
        删除数据数据表 db_delete("JDBC-Mysql","qa_source.test1")
        :param text_type:
        :param db_type:
        :param table:
        :return:
        """
        db_delete_res = self.d_api.db_delete_case(db_type, table, text_type)
        return jsonify(db_delete_res)

    def exec_customer_sql(self, db_type, table, sql):
        """
        查询数据数据表count值 exec_customer_sql("JDBC-Mysql","qa_source.aaa1_ddl","ALTER TABLE qa_source.aaa1_ddl DROP id_11;")
        :param db_type:
        :param table:
        :param sql:
        :return:
        """
        db_delete_res = self.d_api.exec_customer_sql(db_type, table, sql)
        return jsonify(db_delete_res)

    def query_alert_detail(self, job_name):
        res = self.wt_api.query_alert_detail(job_name)
        return jsonify(res)

    def db_get_count(self, db_type, table, text_type=None):
        """
        查询数据数据表count值 db_get_count("JDBC-Mysql","qa_source.test1")
        :param text_type:
        :param db_type:
        :param table:
        :return:
        """
        db_delete_res = self.d_api.db_select_count_case(db_type, table, text_type)
        return jsonify(db_delete_res)

    def delete_project_data(self, project_name, job_name):
        self.wt_api.stop_stream_task(project_name)
        delete_project_data = self.ws_api.delete_project_data(project_name, job_name)
        return jsonify(delete_project_data)

    def db_create_data(self, db_type, table, num):
        db_create_res = self.d_api.db_create_data_case(db_type, table, num)
        return jsonify(db_create_res)

    def db_oracle_make(self, db, table, num):
        db_create_res = self.d_api.db_oracle_make(db, table, num)
        return jsonify(db_create_res)

    def db_deleted_data(self, db_type, table):
        db_deleted_data_res = self.d_api.db_deleted_data_case(db_type, table)
        return jsonify(db_deleted_data_res)

    def db_update_data(self, db_type, table):
        db_update_data_res = self.d_api.db_update_data_case(db_type, table)
        return jsonify(db_update_data_res)

    def convert_value(self, val):
        """递归地将所有不可序列化的类型转换为可序列化的类型。"""
        if isinstance(val, decimal.Decimal):
            return float(val)
        elif isinstance(val, (date, datetime)):
            return val.isoformat()
        elif isinstance(val, list):
            return [self.convert_value(i) for i in val]
        elif isinstance(val, dict):
            return {k: self.convert_value(v) for k, v in val.items()}
        else:
            return val

    def lists_are_equal(self, list1, list2):
        if isinstance(list1, bool) and isinstance(list2, bool):
            return list1 == list2

        if not isinstance(list1, list) or not isinstance(list2, list):
            return False

        if len(list1) != len(list2):
            return False

        # 确保所有值都被转换
        converted_list1 = [self.convert_value(item) for item in list1]
        converted_list2 = [self.convert_value(item) for item in list2]

        # 将字典排序以确保比较顺序一致
        def sort_key(value):
            if isinstance(value, dict):
                return sorted(value.items())  # 将字典项转换为排序的元组列表
            return value

        # 额外调试输出以确认转换后的值
        print("Converted List 1:", converted_list1)
        print("Converted List 2:", converted_list2)

        # 比较两个转换后的列表，使用 key 排序处理字典的比较
        return sorted(converted_list1, key=sort_key) == sorted(converted_list2, key=sort_key)

    def db_check_update_data(self, source_db_type, source_table, sink_db_type, sink_table):
        response_data = {'message': '', 'data': []}

        source_data_res = self.d_api.get_db_data_case(source_db_type, source_table)
        time.sleep(5)
        sink_data_res = self.d_api.get_db_data_case(sink_db_type, sink_table)
        print(source_data_res)
        print(sink_data_res)
        if source_data_res['message'] == "Success" and sink_data_res['message'] == "Success":
            if self.lists_are_equal(source_data_res['data'], sink_data_res['data']):
                response_data.update({'message': "Success", 'data': "source、sink对比一致"})
            else:
                logger.info("source: 数据是: {}".format(source_data_res))
                logger.info("sink: 数据是 {}".format(sink_data_res))
                response_data.update({'message': "fail", 'data': "对比失败，请检查source、sink数据源"})
        else:
            response_data.update({'message': "fail", 'data': "数据获取失败，请检查数据库连接或查询"})

        return jsonify(response_data)


if __name__ == '__main__':
    wt_m = WTModel()
